/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package session.stateless;

import entity.Employee;
import entity.Inventory;
import entity.MaterialRequired;
import entity.MaterialRequirementPlan;
import entity.Product;
import entity.ProductionBatch;
import entity.ProductionScheduleDay;
import entity.PurchaseItem;
import entity.RawMaterial;
import entity.RawMaterialDelivery;
import entity.RawMaterialPurchaseOrder;
import entity.Supplier;
import entity.TrackingItem;
import entity.Warehouse;
import entity.WarehouseZone;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author Wx
 */
@Stateless
public class WarehouseSessionBean implements WarehouseSessionBeanLocal {

    @PersistenceContext
    private EntityManager entityManager;
    
    @Override
    public void removeInventory(Long inventoryId) {
        Inventory i = entityManager.find(Inventory.class, inventoryId);
        
        entityManager.remove(i);
        entityManager.flush();
    }
    
    @Override
    public void updateMaterialRequired(MaterialRequired mr) {
        MaterialRequired temp = entityManager.find(MaterialRequired.class, mr.getId());
        
        temp.setWeight(mr.getWeight());
        
        entityManager.persist(temp);
        entityManager.flush();
    }
    
    @Override
    public void removeRMDFromWH(Long warehouseId, Long rmdId) {
        Warehouse wh = entityManager.find(Warehouse.class, warehouseId);
        RawMaterialDelivery rmd = entityManager.find(RawMaterialDelivery.class, rmdId);
        
        wh.getRawMaterialDeliveries().remove(rmd);
        
        entityManager.persist(wh);
        entityManager.flush();
    }

    @Override
    public void updateInventory(Inventory inventory, TrackingItem ti) {
        Inventory temp = entityManager.find(Inventory.class, inventory.getId());

        List<TrackingItem> trackingItems = temp.getTrackingItems();

        trackingItems.add(ti);

        temp.setTrackingItems(trackingItems);

        entityManager.persist(temp);
        entityManager.flush();
    }

    @Override
    public void updateInventory(Inventory inventory) {
        Inventory temp = entityManager.find(Inventory.class, inventory.getId());

        if (inventory.getProduct() != null) {
            Product p = entityManager.find(Product.class, inventory.getProduct().getCode());

            temp.setProduct(p);
        } else {
            RawMaterial rm = entityManager.find(RawMaterial.class, inventory.getRawMaterial().getId());

            temp.setRawMaterial(rm);
        }

        temp.setQuantity(inventory.getQuantity());

        entityManager.persist(temp);
        entityManager.flush();
    }

    @Override
    public Inventory getInventoryByProduct(String name) {
        Query query = entityManager.createQuery("SELECT i FROM Inventory i");

        for (Object o : query.getResultList()) {
            Inventory i = (Inventory) o;

            if (i.getProduct() != null & i.getProduct().getName().equals(name)) {
                return i;
            }
        }

        return null;
    }

    @Override
    public Inventory getInventoryByRawMaterial(String name) {
        Query query = entityManager.createQuery("SELECT i FROM Inventory i");

        for (Object o : query.getResultList()) {
            Inventory i = (Inventory) o;

            if (i.getRawMaterial() != null && i.getRawMaterial().getName().equals(name)) {
                return i;
            }
        }

        return null;
    }

    @Override
    public void deleteZoneFromWarehouse(Long warehouseId, Long zoneId) {
        Warehouse temp = entityManager.find(Warehouse.class, warehouseId);
        WarehouseZone temp2 = entityManager.find(WarehouseZone.class, zoneId);

        temp.getWarehouseZones().remove(temp2);

        entityManager.persist(temp);
        entityManager.flush();
    }

    @Override
    public void updateWarehouseZone(WarehouseZone wz) {
        WarehouseZone temp = getWarehouseZone(wz.getId());

        temp.setZoneName(wz.getZoneName());
        temp.setCurrentQuantity(wz.getCurrentQuantity());
        temp.setQuantityLimit(wz.getQuantityLimit());
        temp.setType(wz.getType());

        entityManager.persist(temp);
        entityManager.flush();
    }

    @Override
    public WarehouseZone getWarehouseZone(Long id) {
        WarehouseZone wz = entityManager.find(WarehouseZone.class, id);

        return wz;
    }

    @Override
    public void addWarehouseZone(WarehouseZone warehouseZone) {
        entityManager.persist(warehouseZone);
        entityManager.flush();
    }

    @Override
    public WarehouseZone getWarehouseZoneByName(String name, Long id) {
        Query query = entityManager.createQuery("SELECT wz FROM WarehouseZone wz");

        for (Object o : query.getResultList()) {
            WarehouseZone wz = (WarehouseZone) o;

            if (wz.getZoneName().equals(name) && wz.getId() != id) {
                return wz;
            }
        }

        return null;
    }

    @Override
    public WarehouseZone getWarehouseZone(String name) {
        Query query = entityManager.createQuery("SELECT wz FROM WarehouseZone wz");

        for (Object o : query.getResultList()) {
            WarehouseZone wz = (WarehouseZone) o;

            if (wz.getZoneName().equals(name)) {
                return wz;
            }
        }

        return null;
    }

    @Override
    public List<WarehouseZone> getWarehouseZones() {
        Query query = entityManager.createQuery("SELECT wz FROM WarehouseZone wz");

        ArrayList<WarehouseZone> warehouseZones = new ArrayList<WarehouseZone>();

        for (Object o : query.getResultList()) {
            WarehouseZone wz = (WarehouseZone) o;

            warehouseZones.add(wz);
        }

        return warehouseZones;
    }

    @Override
    public List<Warehouse> getWarehouses() {
        Query query = entityManager.createQuery("SELECT w FROM Warehouse w");

        ArrayList<Warehouse> warehouses = new ArrayList<Warehouse>();

        for (Object o : query.getResultList()) {
            Warehouse w = (Warehouse) o;

            warehouses.add(w);
        }

        return warehouses;
    }

    @Override
    public Warehouse getWarehouse(Long warehouseId) {
        Warehouse w = entityManager.find(Warehouse.class, warehouseId);

        return w;
    }

    @Override
    public void updateWarehouse(Long warehouseId, ProductionBatch productionBatch) {
        
        try
        {
        Warehouse w = getWarehouse(warehouseId);
        List<ProductionBatch> temp = w.getProductionBatches();

        ProductionBatch pb = entityManager.find(ProductionBatch.class, productionBatch.getId());
        temp.add(pb);
        w.setProductionBatches(temp);
        entityManager.persist(w);
        }catch (Exception ex){}
    }

    @Override
    public void updateWarehouse(Long warehouseId, RawMaterialDelivery rawMaterialDelivery) {
        Warehouse w = getWarehouse(warehouseId);
        
        RawMaterial rm = entityManager.find(RawMaterial.class, rawMaterialDelivery.getMaterialRequired().getRawMaterial().getId());

        MaterialRequired mr = rawMaterialDelivery.getMaterialRequired();
        mr.setRawMaterial(rm);

        Employee e = entityManager.find(Employee.class, rawMaterialDelivery.getWarehouseRep().getUserId());

        Supplier s = entityManager.find(Supplier.class, rawMaterialDelivery.getSupplier().getSupplierId());

        RawMaterialPurchaseOrder rmpo = entityManager.find(RawMaterialPurchaseOrder.class, rawMaterialDelivery.getRawMaterialPurchaseOrder().getId());

        WarehouseZone wz = entityManager.find(WarehouseZone.class, rawMaterialDelivery.getWarehouseZone().getId());
        
        rawMaterialDelivery.setWarehouseZone(wz);
        rawMaterialDelivery.setMaterialRequired(mr);
        rawMaterialDelivery.setSupplier(s);
        rawMaterialDelivery.setWarehouseRep(e);
        rawMaterialDelivery.setRawMaterialPurchaseOrder(rmpo);

        List<RawMaterialDelivery> temp = w.getRawMaterialDeliveries();

        temp.add(rawMaterialDelivery);

        w.setRawMaterialDeliveries(temp);

        entityManager.persist(w);
    }

    @Override
    public void updateWarehouse(Long warehouseId, WarehouseZone warehouseZone) {
        Warehouse w = getWarehouse(warehouseId);

        WarehouseZone wz = getWarehouseZone(warehouseZone.getZoneName());

        w.getWarehouseZones().add(wz);

        entityManager.persist(w);
    }

    @Override
    public Integer getInventory(Long warehouseId, String code) 
    {
        Warehouse w = getWarehouse(warehouseId);
        ArrayList<ProductionBatch> productionBatches = new ArrayList(w.getProductionBatches());
        Integer quantity = 0;
        for (ProductionBatch productionBatch : productionBatches) {
            if (productionBatch.getProduct().getCode().compareTo(code) == 0) 
            {
                quantity +=productionBatch.getQuantity() - productionBatch.getUtilizedQuantity();
              
            }
        }
        System.out.println ("CURRENT INVENTORY:" + quantity);
        return quantity;
    }

    @Override
    public Date checkDateFromInventory(String code, Integer quantity) {
        Warehouse wh = getWarehouse(Long.parseLong("1000"));
        ArrayList<ProductionBatch> pbs = new ArrayList<ProductionBatch>(wh.getProductionBatches());
        ProductionScheduleDay psd = null;

        Integer count = quantity;

        for (ProductionBatch pb : pbs) {
            if (pb.getProduct().getCode().compareTo(code) == 0 && pb.getQuantity() - pb.getUtilizedQuantity() > 0) {

                psd = pb.getProductionScheduleDay();
                count -= (pb.getQuantity() - pb.getUtilizedQuantity());
            }
        }

        if (count < 0 && psd != null) {
            Calendar cal = Calendar.getInstance();
            cal.set(psd.getProductionSchedule().getOperationYear(), psd.getProductionSchedule().getOperationMonth() - 1, psd.getCurrentDay());
            cal.add(cal.DAY_OF_MONTH, +7);
            return cal.getTime();
        }
        return null;
    }
}
